<template>
  <div class="ProfitQuery">
    <div class="ProfitQuery-toolbar">
      <el-form :model="form" ref="formRef" label-width="100px" class="ProfitQuery-form" inline>
        <el-form-item label="模式" prop="mode">
          <el-radio-group v-model="form.mode" @change="handleModeChange">
            <el-radio-button label="year">年</el-radio-button>
            <el-radio-button label="month">月</el-radio-button>
            <el-radio-button label="day">日</el-radio-button>
          </el-radio-group>
        </el-form-item>
        <template v-if="form.mode==='year'">
          <el-form-item label="年份范围" required>
            <div class="ProfitQuery-range">
              <el-select v-model="yearRange.start" placeholder="开始年" class="ProfitQuery-range-select"
                         @change="validateYearRange">
                <el-option v-for="y in yearOptions" :key="y" :label="y" :value="y"/>
              </el-select>
              <span class="ProfitQuery-range-sep">-</span>
              <el-select v-model="yearRange.end" placeholder="结束年" class="ProfitQuery-range-select"
                         @change="validateYearRange">
                <el-option v-for="y in yearOptions" :key="'e'+y" :label="y" :value="y"/>
              </el-select>
            </div>
          </el-form-item>
        </template>
        <template v-else-if="form.mode==='month'">
          <el-form-item label="月份范围" required>
            <el-date-picker v-model="monthRange" type="monthrange" range-separator="至" start-placeholder="开始月份"
                            end-placeholder="结束月份" :disabled-date="disableFutureMonth" value-format="YYYY-MM"
                            @change="validateMonthRange" :clearable="false" :editable="false"/>
          </el-form-item>
        </template>
        <template v-else>
          <el-form-item label="日期范围" required>
            <el-date-picker v-model="dayRange" type="daterange" range-separator="至" start-placeholder="开始日期"
                            end-placeholder="结束日期" value-format="YYYY-MM-DD" :disabled-date="disableFutureDay"
                            @change="validateDayRange" :clearable="false" :editable="false" :shortcuts="dayShortcuts"/>
          </el-form-item>
        </template>
        <el-form-item>
          <el-button type="primary" @click="handleQuery">查询</el-button>
          <el-button @click="handleReset">重置</el-button>
        </el-form-item>
      </el-form>
    </div>

    <div class="ProfitQuery-chartWrapper" :class="{ 'is-loading': loading }">
      <div v-if="loading" class="ProfitQuery-chartLoading">加载中...</div>
      <div v-else-if="!chartData.length" class="ProfitQuery-chartEmpty">请选择条件后点击查询，显示利润折线图</div>
      <div v-else ref="chartRef" class="ProfitQuery-chart"></div>
    </div>
  </div>
</template>

<script setup>
import {ref, reactive, onMounted, onBeforeUnmount, nextTick, watch} from 'vue'
import {ElMessage} from 'element-plus'
import * as echarts from 'echarts'
import {listProfits} from '../../../api/profitApi.js'

// 表单数据
const formRef = ref()
const form = reactive({mode: 'year'})

// 年份范围
const currentYear = new Date().getFullYear()
const yearOptions = Array.from({length: 50}).map((_, i) => currentYear - i) // 近 50 年
const yearRange = reactive({start: currentYear - 4, end: currentYear}) // 默认 5 年（含本年）

// 月份范围 (monthrange 返回 [start,end])
const monthRange = ref([])
// 日期范围
const dayRange = ref([])

// 折线图数据
const chartRef = ref(null)
let chartInstance = null
const chartData = ref([]) // {label,value}
const loading = ref(false)

// 初始化默认月份 / 日期范围
const initMonthRange = () => {
  const start = `${currentYear}-01`
  const end = `${currentYear}-12`
  monthRange.value = [start, end]
}
const formatDate = (d) => {
  const y = d.getFullYear();
  const m = String(d.getMonth() + 1).padStart(2, '0');
  const day = String(d.getDate()).padStart(2, '0');
  return `${y}-${m}-${day}`
}
const initDayRange = () => {
  const end = new Date()
  const start = new Date(end.getTime() - (7 - 1) * 24 * 3600 * 1000)
  dayRange.value = [formatDate(start), formatDate(end)]
}

// 模式切换
const handleModeChange = async () => {
  if (form.mode === 'year') {
    yearRange.start = currentYear - 4
    yearRange.end = currentYear
  } else if (form.mode === 'month') {
    initMonthRange()
  } else {
    initDayRange()
  }
  chartData.value = []
  disposeChart()
  await nextTick()
  handleQuery()
}

// 约束校验
const validateYearRange = () => {
  if (yearRange.start > yearRange.end) yearRange.end = yearRange.start
  const span = yearRange.end - yearRange.start + 1
  if (span > 24) {
    yearRange.start = yearRange.end - 23
    ElMessage.warning('年份跨度不能超过 24 年')
  }
}
const validateMonthRange = () => {
  if (!monthRange.value || monthRange.value.length !== 2) return
  const [s, e] = monthRange.value
  // 计算月差
  const [sy, sm] = s.split('-').map(n => Number(n))
  const [ey, em] = e.split('-').map(n => Number(n))
  let diff = (ey - sy) * 12 + (em - sm) + 1
  if (diff > 24) {
    ElMessage.warning('月份跨度不能超过 24 个月')
    // 自动截断为 24 个月
    const date = new Date(s + '-01')
    date.setMonth(date.getMonth() + 23)
    const ny = date.getFullYear();
    const nm = String(date.getMonth() + 1).padStart(2, '0')
    monthRange.value = [s, `${ny}-${nm}`]
  }
}
const validateDayRange = () => {
  if (!dayRange.value || dayRange.value.length !== 2) return
  const [s, e] = dayRange.value
  const diffDays = (new Date(e).getTime() - new Date(s).getTime()) / 86400000 + 1
  if (diffDays > 60) {
    ElMessage.warning('日期跨度不能超过 60 天')
    const start = new Date(e)
    start.setDate(start.getDate() - (60 - 1))
    dayRange.value = [formatDate(start), e]
  }
}

// 日范围快捷选项
const dayShortcuts = [
  {
    text: '近7天',
    value: () => {
      const end = new Date()
      const start = new Date(end.getTime() - (7 - 1) * 86400000)
      return [formatDate(start), formatDate(end)]
    }
  },
  {
    text: '近30天',
    value: () => {
      const end = new Date()
      const start = new Date(end.getTime() - (30 - 1) * 86400000)
      return [formatDate(start), formatDate(end)]
    }
  }
]

// 调整未来可选限制：月份 <= 当前月 +6；日期 <= 今天 +30 天
const disableFutureMonth = (d) => {
  if (!d) return false
  const now = new Date()
  const monthsDiff = (d.getFullYear() - now.getFullYear()) * 12 + (d.getMonth() - now.getMonth())
  return monthsDiff > 6 // 超过 6 个月后禁用
}
const disableFutureDay = (d) => {
  if (!d) return false
  const now = new Date();
  const max = new Date(now.getTime() + 30 * 86400000) // 允许未来 30 天
  return d.getTime() > max.getTime()
}

// 新增工具函数：获取某月最后一天
const getLastDayOfMonth = (year, month) => {
  return new Date(year, month, 0).getDate() // month 为 1-12 中的数字
}

// 构建标准化查询条件（统一 startDate / endDate）
const buildCondition = () => {
  if (form.mode === 'year') {
    const startYear = yearRange.start
    const endYear = yearRange.end
    return {
      mode: 'year',
      startDate: `${startYear}-01-01`,
      endDate: `${endYear}-12-31`,
      yearRange: {start: startYear, end: endYear}
    }
  }
  if (form.mode === 'month') {
    const [s, e] = monthRange.value || []
    if (!s || !e) return null
    const [sy, sm] = s.split('-').map(Number)
    const [ey, em] = e.split('-').map(Number)
    const endDay = getLastDayOfMonth(ey, em)
    return {
      mode: 'month',
      startDate: `${s}-01`,
      endDate: `${e}-${String(endDay).padStart(2, '0')}`,
      monthRange: {start: s, end: e}
    }
  }
  const [ds, de] = dayRange.value || []
  if (!ds || !de) return null
  return {mode: 'day', startDate: ds, endDate: de, dayRange: {start: ds, end: de}}
}

// 监听数据变化，DOM 出现后再渲染
watch(chartData, async (val) => {
  if (!val || !val.length) return
  await nextTick()
  renderChart()
})

// 查询（调用后端）
const handleQuery = async () => {
  if (form.mode === 'year') {
    validateYearRange()
  } else if (form.mode === 'month') {
    validateMonthRange()
    if (!monthRange.value || monthRange.value.length !== 2) return ElMessage.error('请选择月份范围')
  } else {
    validateDayRange()
    if (!dayRange.value || dayRange.value.length !== 2) return ElMessage.error('请选择日期范围')
  }
  const condition = buildCondition()
  if (!condition) return
  loading.value = true
  chartData.value = []
  disposeChart()
  try {
    const res = await listProfits(condition)
    const list = res.list || (res.data && res.data.list) || []
    chartData.value = list.map(i => ({label: String(i.label), value: Number(i.profit || 0)}))
    if (!chartData.value.length) {
      ElMessage.info('暂无数据')
    }
    // 不直接调用 renderChart，交由 watch + nextTick
  } catch (e) {
  } finally {
    loading.value = false
  }
}

// 重置
const handleReset = () => {
  form.mode = 'year'
  yearRange.start = currentYear - 4
  yearRange.end = currentYear
  initMonthRange()
  initDayRange()
  chartData.value = []
  disposeChart()
}

// 图表渲染（根据数据动态调整 y 轴范围）
const renderChart = () => {
  if (!chartRef.value) return
  const xData = chartData.value.map(i => i.label)
  const yData = chartData.value.map(i => i.value)
  if (!chartInstance) {
    chartInstance = echarts.init(chartRef.value)
    window.addEventListener('resize', handleResize)
  }
  const allSame = yData.length > 0 && yData.every(v => v === yData[0])
  const yMin = allSame ? yData[0] - 1 : null
  const yMax = allSame ? yData[0] + 1 : null
  const option = {
    tooltip: {trigger: 'axis', formatter: (params) => params.map(p => `${p.axisValue}: ${p.data} 元`).join('<br/>')},
    grid: {left: 40, right: 20, top: 40, bottom: 40},
    xAxis: {type: 'category', data: xData, boundaryGap: false},
    yAxis: {type: 'value', name: '利润', axisLabel: {formatter: v => v}, min: yMin, max: yMax},
    series: [{name: '利润', type: 'line', data: yData, smooth: false, showSymbol: allSame, areaStyle: {opacity: 0.08}}]
  }
  chartInstance.setOption(option)
  chartInstance.resize()
}

const handleResize = () => {
  chartInstance && chartInstance.resize()
}
const disposeChart = () => {
  if (chartInstance) {
    window.removeEventListener('resize', handleResize)
    chartInstance.dispose()
    chartInstance = null
  }
}

onMounted(async () => {
  initMonthRange()
  initDayRange()
  await nextTick()
  await handleQuery()
})

onBeforeUnmount(() => {
  disposeChart()
})
</script>

<style scoped lang="scss">
.ProfitQuery {
  &-toolbar {
    padding: 16px 0;
    border-bottom: 1px solid #eee;
  }

  &-form {
    display: flex;
    flex-wrap: wrap;
    gap: 16px;
  }

  &-range {
    display: flex;
    align-items: center;
    gap: 8px;
  }

  &-range-select {
    width: 120px;
  }

  &-range-sep {
    color: #606266;
  }

  &-chartWrapper {
    padding: 16px 0;
    position: relative;

    &.is-loading {
      .ProfitQuery-chartLoading {
        display: flex;
      }
    }
  }

  &-chart {
    width: 100%;
    height: 420px;
  }

  &-chartEmpty {
    width: 100%;
    height: 420px;
    display: flex;
    align-items: center;
    justify-content: center;
    color: #909399;
    font-size: 14px;
    border: 1px dashed #dcdfe6;
    background: #fafafa;
  }

  &-chartLoading {
    position: absolute;
    left: 0;
    top: 0;
    right: 0;
    bottom: 0;
    background: rgba(255, 255, 255, .75);
    display: none;
    align-items: center;
    justify-content: center;
    font-size: 14px;
    color: #606266;
    border: 1px solid #ebeef5;
  }
}
</style>
